package com.example.myapplication;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.ArrayList;



public class MyKLineView extends View {
    private Paint mPaint;
    private Paint mMovingPaint;

    private static final int HANDLER_WHAT = 100;

    private static final int RATE = 1; // 移动速率

    private int mR = 0;  // 移动速率

    private int mRate = RATE;   // 速率
    private static final int FRAME = 1000;  // 1000帧

    private PointF start,end,control;
    private Path path = new Path();

    //控制点集合
    private ArrayList<PointF> mControlPoints = null;

    private ArrayList<PointF> mBezierPoints = null; // 贝塞尔曲线点集

    private PointF mBezierPoint = null; // 贝塞尔曲线移动点



    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == HANDLER_WHAT) {
                mR += mRate;
                if (mR >= mBezierPoints.size()) {
                    removeMessages(HANDLER_WHAT);
                    mR = 0;
                    return;
                }
                if (mR != mBezierPoints.size() - 1 && mR + mRate >= mBezierPoints.size()) {
                    mR = mBezierPoints.size() - 1;
                }
                // Bezier点
                mBezierPoint = new PointF(mBezierPoints.get(mR).x, mBezierPoints.get(mR).y);
                // 切线点
                invalidate();
            }
        }
    };




    public MyKLineView(Context context) {
        super(context);
        init();
    }

    public MyKLineView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyKLineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void  init(){
        mMovingPaint = new Paint();
        mMovingPaint.setColor(Color.BLACK);
        mMovingPaint.setAntiAlias(true);
        mMovingPaint.setStyle(Paint.Style.FILL);
        int w = getResources().getDisplayMetrics().widthPixels;
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(8);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setTextSize(60);
        start = new PointF(200,200);
        end = new PointF(700,1800);
//        control = new PointF(800,1000);
        mControlPoints = new ArrayList<>();
        mControlPoints.add(start);
//        mControlPoints.add(control);
        mControlPoints.add(end);
        mBezierPoints = buildBezierPoints();
    }



    private float deCasteljauX(int i, int j, float t) {
        if (i == 1) {
            return (1 - t) * mControlPoints.get(j).x + t * mControlPoints.get(j + 1).x;
        }
        return (1 - t) * deCasteljauX(i - 1, j, t) + t * deCasteljauX(i - 1, j + 1, t);
    }
    private float deCasteljauY(int i, int j, float t) {
        if (i == 1) {
            return (1 - t) * mControlPoints.get(j).y + t * mControlPoints.get(j + 1).y;
        }
        return (1 - t) * deCasteljauY(i - 1, j, t) + t * deCasteljauY(i - 1, j + 1, t);
    }

    //创建贝塞曲线集合点
    private ArrayList<PointF> buildBezierPoints() {
        ArrayList<PointF> points = new ArrayList<>();
        int order = mControlPoints.size() - 1;
        float delta = 1.0f / FRAME;
        for (float t = 0; t <= 1; t += delta) {
            // Bezier点集
            points.add(new PointF(deCasteljauX(order, 0, t), deCasteljauY(order, 0, t)));
        }
        return points;
    }

    @Override
    protected void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
        mPaint.setColor(Color.GRAY);
        mPaint.setStrokeWidth(20);
        canvas.drawPoint(start.x,start.y,mPaint);
        canvas.drawPoint(end.x,end.y,mPaint);
//        canvas.drawPoint(control.x,control.y,mPaint);

        //绘制辅助线
//        mPaint.setStrokeWidth(4);
//        int size = mControlPoints.size();
//        PointF pointF;
//        for (int i=0;i<size;i++){
//            pointF = mControlPoints.get(i);
//            if(i>0){
//                canvas.drawLine(mControlPoints.get(i-1).x,mControlPoints.get(i-1).y,pointF.x,pointF.y,mPaint);
//            }
//        }

        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(20);
        //绘制开始地点
        if (mBezierPoint == null) {
            mPaint.reset();
            mBezierPoint = mBezierPoints.get(0);
            path.moveTo(mBezierPoint.x, mBezierPoint.y);
        }

        //绘制Bezier曲线
        path.lineTo(mBezierPoint.x,mBezierPoint.y);
        canvas.drawPath(path,mPaint);
        canvas.drawCircle(mBezierPoint.x,mBezierPoint.y,12,mMovingPaint);
        mHandler.removeMessages(HANDLER_WHAT);
        mHandler.sendEmptyMessage(HANDLER_WHAT);

    }

}
